Thinkphp 
    架构的方式 MVC 
        M：model 模型 用来对数据进行CURD 操作
        V：view 视图 html页面
        C：controller 控制器 用来写业务逻辑

    用户 -> 输入url -> 找到控制器 (模块home/admin/控制器/方法) -> 业务(加载模型) -> 赋值给视图 -> 由view视图来做显示 



第三阶段 WEB前端框架
    vue + nodejs 
    Vue2 + Vue3 


Vue 有两张安装方式
    1、利用脚手架的方式去安装(推荐使用)
        nodejs
        webpack es6  eslint 自动化工具

    2、类似于 jquery 直接引入一个js文件 单页面应用


指令
    v-model  绑定数据 (双向绑定 当检测到有变化的时候，不管是页面  还是 data的数据 都会跟着一起变化)
    v-model="绑定的是变量"  变量是data里面定义的


正常在模板中输出变量的方式 ::  大胡子写法 
{{ 变量名称 }}


Vue 
    类似于 MVC 架构方式 
    MVVM  升级版 数据的双向绑定
        M： model模型(数据)
        V： 视图 (界面)
        VM(C)：桥梁
            Controller 控制器
            VM：视图模型(组件) 组件化开发

常用的指令

v-if 条件判断
v-show  显示和隐藏
v-model  数据绑定
v-for  循环
v-html 输出带有html标签的变量
v-pre  不解析变量直接输出 原本的内容
v-bind 缩写 :属性="变量"  绑定属性
v-on 绑定事件


new Vue 创建一个vue应用 
el属性： 绑定vue的根元素
data属性： 用来定义vue应用中的数据部分
        存放的是 我们标量的数据 基本的类型 字符串、布尔、数组
methods： 定义方法
computed: 计算属性 == data 属性, data / computed 不能够出现重复   区别在于  计算属性 是可以写一部分的逻辑进去
watch: 监听器 可以监听 data数据里面的变量 变化前和变化后的结果
filters： 过滤器，对我们的变量内容来进行一些调整 或者是格式的变化   例如： num = 1000000 100,1000

$refs 获取dom元素
this 代表整个 vue的应用
获取data数据   this.data的变量名

在js中 一般操作的元素  dom节点

在vue中获取dom的元素  ref 属性

Vue2.x 版本
Vue生命周期 => app生命周期
new Vue 创建一个Vue应用
beforeCreate 第一个生命周期钩子 创建前的钩子
Data 绑定数据的双向关系
初始化事件(框架的事件、和我们methods里面自定义的事件方法)
created 第二个生命周期钩子函数  创建后的钩子函数
找el 根元素  对根元素 进行 编译
beforeMount 第三个生命周期的钩子函数  挂载前的钩子 接口请求
创建根元素，并将结果替换上去
mounted 第四个生命周期的函数， 挂载后的生命周期函数

beforeUpdate  数据更新前的钩子
updated   数据更新后的钩子函数 自动触发的

---------- 页面  已经渲染完成 并且显示出来  ----  
从 A 界面  跳转到了  B 界面
销毁前
beforeDestroy 

销毁后
Destroyed

整个生命周期的钩子函数： 8个
创建前后
挂载前后
更新前后 可以用 watch 监听器来替换
销毁前后



指令
    v-model 数据绑定
    v-bind  属性绑定
    v-for  循环
    v-if  条件
    v-show  显示和隐藏
    v-on 事件绑定
    v-once  仅绑定一次
    v-html 输出标签并解析
    v-pre  不解析 

属性 除了可以在 new Vue 根组件中使用以外 还可以在 子组件中也是可以使用的
    el 绑定根元素
    data 数据  子组件 是 个 方法 方法返回对象 vue2 
    methods 方法
    filters 过滤器
    computed 计算属性
    watch 监听器
    $ref 获取dom属性 
    components  加载组件的属性
    
生命周期
    创建前 
    创建后
    挂载前 
    挂载后 
    更新前
    更新后 
    销毁前
    销毁后 

组件 MV VM 桥梁(监听)  VM === Controller 控制器 === 组件 


走 apache  http 访问  
走  file 协议 本地


域名 -> 备案 (1 - 2星期)
服务器 IP地址  域名去访问

ask 论坛项目

磁盘 ： 40G 

5 ~ 6 
半年 : 300

TP： 
    11月 20 日 在本地将前后台做好

组件是可以传值的
在父子组件通信的时候 
父组件 传递 数据 给子组件的时候 用  属性传递 并且 传递的这个属性必须要在字组件内有所定义

子组件  传递 数据 给父组件 用 自定义事件 
自带一些 js 事件 click mouseover

核心的原理： 让子组件 去 触发 自定义事件  在触发的时候 传参过去 然后触发的事件方法 在 父组件里面定义  这样 就可以在父当中去接收到参数

插槽 slot
作用：可以在调用组件的时候，随时替代他


Thinkphp 开箱即用 集成MVC 验证码 分页 

home/Controller/Index.php  => index 方法 

Vue 用时加载 什么时候用 什么时候加载
    Vue  只是提供 一套 标准的MVVM的框架流程 除此之外 啥都没有

Vue项目开发 输入一套全家桶
Vue 
通过一些url地址 来加载不同的组件 

/   =>  属于 默认打开的界面
/user   => user.vue  => 组件
/order  => order.vue   => 组件

使用 vue-router  来给vue 增加一个路由功能

Vue 是 单页面开发 实际上是根据 不同的路由地址 来 加载 不同的组件 进行无刷新的切换  所以 我们页面  就达到 不同路由地址 加载不同的界面进来

TP =>  layout 模板布局

根据不同的路由地址 来切换不同组件

www.ask.com/admin/user/post/info


路由跳转：
1、通过 router-link 组件来跳转 
2、通过 在 vue应用里面  通过事件跳转  this.$router.push('路由的地址')


/user/:id  name:'info'   定义传参  
<router-link  :to="{name:'info', params:{id:1}}">  传参
this.$route.params.id   获取传参

/user?name=张三   定义参数
<router-link :to="{path:'/user', query:{name:'张三'}}"> 传参
this.$route.query.name  获取传参

this.$route.push  跳转路由 

this.$route.push('/user')   //不带参数
this.$route.push({path:'/user', query:{name:"张三"}}) //带参数

location.reload()  //刷新

location.go(1) 前进 -1 后退

this.$router.go(0) //刷新当前界面
this.$router.go(1) //前进
this.$router.go(-1) //后退


路由守卫： 
    会员中心 => 想要进去 一定要先去判断是否有没有登录 判断是否有cookie

cookie 放到客户端 把一些不重要的信息 或者是公开的信息 放到客户端 目的 平衡服务器的压力

session  放到服务器 安全 服务器压力太大
会员有多少量 -> 多
管理员有多少量 -> 少


Vue 访问形式
路由守卫：

url -> 路由 -> 路由守卫 -> 加载组件 -> 渲染到界面
                -> 判断是否有登录 -> 没登录跳转到登录界面

/user -> 会员中心 -> 先登录 -> 判断是否有没有登录

history结构
域名 + 路由地址 

localhost + /login


---------------------------------------------------------------
yarn create vite shop --template vue

目录结构
index.html     是页面的入口文件
node_modules/   这个项目 通过npm 安装的 依赖包目录
package.json    项目依赖包的配置文件
public/          公共访问目录 用来存放 js / css / images
vite.config.js    构建工具的配置文件 -> 接口的代理，打包的配置
yarn 和 npm 包管理工具 
yarn.lock      防止重复安装
package.lock    
src             项目开发的源码目录
    main.js     程序的入口文件
    App.vue     根组件
    components/   子组件的文件夹
    assets/    也是用于放静态资源 logo 插件js 封装的服务

上线
1、 yarn build  
    cnpm run build 

2、dist目录 打包生成出来的目录

同源策略
www.baidu.com  

www.baidu.com
www.google.com
非同源策略 跨域 怎么解决跨域 jsonp

走域名  配置一个站点来进行访问
用phpstudy  创建一个站点  指向的目录

dev 命令   localhost:3000  

build 命令  必须要用站点
        同步  windows   hosts 文件
        127.0.0.1    www.shop.com 

管理员取得所有权
    把hosts文件复制到桌面  在桌面改完之后 在覆盖到 相应的目录

npm cnpm yarn  只要有一个就可以 
yarn 命令 
npm run 命令


需要在构建工具  vite 里面去 配置一个全局的变量 来代替我们路径



在脚手架里面去添加路由  Vue全家桶  vue-cli + vite + vue-router 
vue-router3 版本


vue-router4 最新

cnpm  或者 yarn 
-S 将安装信息写到配置中 package.json 
cnpm install vue-router@4 -S    

yarn add vue-router@4 -S

创建一个路由文件
src/routers/index.js 

创建对应的组件
src/components/home.vue 
src/components/user.vue 


封装好路由之后，要去main.js 里面引入和挂载
import 引入 
use 挂载

在App.vue中进行渲染
<router-view> 标签


在底部tab.vue中跳转
首页 我的 用 <router-link> 来跳转


不要把所有的控制器方法 写到一个文件中

Vue  改成 类似于 TP 
www.ask.com/admin/user/profile 
             模块  控制器  方法 

控制器
ask/application/admin/Controller/User.php -> function profile 

视图
ask/application/admin/view/admin/user/profile.html


地址URL： localhost:3000/user/base/profile

控制器 -> 视图
路由 -> 组件

/ 

路由结构：
    /src/routers 
        index.js 
        /user
            base.js 
                profile

组件结构
    /src/components 
        /user
            /base
                profile.vue 

改造路由


include php 

js import.meta.globEager 引入某个目录下面的所有文件


../component/user    
可以通过 vite 构建工具 来 注册一个 全局变量
让这个全局变量 来 代替   src/ 根目录

__dirname php 魔术常量  __FILE__  获取文件的绝对路径
获取当前文件所在文件夹的路径

E:/PhpStudy_pro/WWW/shop/src   => @
E:/PhpStudy_pro/WWW/shop/src/components   => components




改造路由
1、配置vite选项 vite.config.js 

地址：localhost:3000/user/base/index
路由：/src/routers/user/base.js
组件：/src/components/user/base/index.vue 
接口：www.ask.com/api/user/base/index 
控制器：ask/application/api/Controllers/User/Base.php -> index 

axios 异步请求工具 http

if($this->request->isPost())
{
    $params = $this-request->params('username');
}


搭建脚手架 -> 装路由 -> 改造路由 -> 封装接口 -> 装UI框架 -> 写业务逻辑 -> 打包上线 -> 发布了


引入UI框架  Vant 移动端
-S 写入到 package.json 中  哪个选项 生产 dependencies
-D 写入到 package.json 中  哪个选项 生产 devDependencies
cnpm install vant@3 -S
yarn add vant@3 -S

2、引入
//引入ui组件
import Vant from 'vant'
import 'vant/lib/index.css'
.use(Vant)   //挂载UI组件


3、使用




home 前台
admin 模块
创建模块 

//创建api(接口)模块
php think build --module api


www.ask.com/ /api /user/base/reigster 

www.ask.com/api/user/base/register 方法


vue这边还没有封装接口 => 改造
vue 不具备发请求的功能  axios 装插件

api/  放接口的
services/  放 我们自定义封装的服务(插件)
    request.js  请求插件

安装axios 
npm install axios -S => 国内(代理)  => 丢包 
yarn add axios -S


http://localhost:3000/api/user/base/register


Thinkphp  apache 80 端口 
域名：www.ask.com 

www.ask.com/api/user/base/register



tp 控制器 success error
会根据你的请求是什么类型 根据类型返回不同的数据结果 

http => 返回跳转界面

xhr => 返回json数据


1、安装VantUI框架
    安装
    cnpm i vant@next -S 

    //挂载 main.js 


2、安装axios异步
    cnpm install axios -S

3、封装接口服务
    /src/serivces/request.js 
    /src/api 
    vite.config.js  =》 设置代理
    main.js =》 挂载api 
    使用 
        this.$api.register()

4、自己的项目要去创建api模块
    https://gitee.com/dancefunk/ask.git

5、注册界面 发起请求接口 返回结果做判断
    /src/components/user/base/register.vue 


安装cookie 
cnpm install vue3-cookies --save

引入和挂载
import VueCookies from 'vue3-cookies'

.use(VueCookies)


第一个：
    把两个仓库都克隆
        vue 
        tp

    配置两个后台
        www.ask.com -> 自己的
        www.asks.com -> 我的 vite.config.js


调错：
    1、是什么错误  百度翻译
    2、具体操作哪个文件 导致的报错
    3、前后端分离  
        后端：看一下接口是否可以访问 www.ask.com/api/user/base/login get 还是 post 
        前端：路由、接口、插件是否安装和挂载 、 方法是否定义
    整个项目是怎样运行 路由 -> 组件


安装地区组件
cnpm install @vant/area-data


收货地址：
    当我们已进入到收货地址列表界面的时候，要先发送一次请求。
    发请求的目的，就是去拿他原有的收货地址数据

当前登录的人 
多条收货地址  5条收货地址

如果有默认收货地址 就返回结果  user_address 
默认：status = 1

随便返回一个


1、已支付、未发货
2、已发货、未收货
3、已收货、未评价
4、已评价
-1、退货


下订单
    积分够不够
    库存够不够

1、下订单 order order_product
2、减库存 product 
3、减积分 user 
4、删除购物车记录  cart 
5、消费记录 user_record

1个订单 有3个商品 
order:1条
order_product : 3条


save 插入  更新 id -> 一位数组

saveAll => 二维数组


ask
    


换一套模板风格


Shop家居商城的前后台部分
    前台中，比如网站的title 和 logo 用接口去调用 系统配置表的数据
    客服电话：需要在后台的系统配置中添加一个官方客户电话.
        <a href="tel:123123123">
    立即购买的流程：
            点击的商品要先加入到购物车里面，然后在去到确认订单界面

    底部导航栏的分类：
            Vant TreeSelect分类选择  自定义内容
            左侧分类 右侧分类的商品 点击商品跳转商品详情界面

    我的
        基本资料

        我的订单
            订单列表
            订单删除
            订单详情
            申请退货(需要界面) 退货申请表 后台审核
            确认收货(不需要界面) 改变订单表 status 状态
            查看物流 可以调用第三方接口(收费)
                https://market.aliyun.com/products/?spm=5176.78296.J_8396760290.11.4f4a5d764gC7V6&c=m&keywords=%E5%BF%AB%E9%80%92
            评价的界面

        消费记录 跟问答一样

        充值 充值表
            提交充值表单 
                充值积分数：
                充值的备注：
                截图信息：
                提交按钮

        充值记录
            列表

    
Ask后台管理
    商品管理
        分类管理

        商品列表

    充值列表
        分页列表
        删除
        审核
            审核通过
                加积分以外 + 根据充值总数来去判断这个人是vip几 
                1000 vip1
                2000 vip2

            审核不通过

    订单管理
        订单列表
            分页列表
            订单详情
            发货(需要界面)

        退货列表(分页列表)
            审核 拒绝审核

    会员列表
        查看订单(只查询这个人的所有订单)
        查看充值记录(只查询这个人的)

    数据统计
        充值统计
        订单统计



-------------------------------------------------------
setup 函数  生命周期函数  要有返回值 return {数据、方法}
    在beforeCreate 之前的钩子函数
ref 定义响应式数据  基础类型
reactive  定义复杂类型的响应式
toRef  抽离单个属性 抽离属性是响应式的
toRefs 抽离多个属性 抽离的所有属性都是响应式

computed()  计算属性方法
watch() 监听器方法
var hello = ref(null)  获取ref='hello' 一个dom元素 要return出去

父子通信 属性 事件 provide(传递)与inject(接收)
provide  需要在父组件中进行传递
inject    在子组件中接收的
Teleport    传送门 有点类似于  公共页面 header footer
        条件：需要一个挂载点  挂载点一般定义到 根目录下面的 index.html
        teleport === slot 插槽


Suspense异步组件
        #default 插槽
        #fallback 正在请求中的插槽

        
插槽和插槽作用域
v-slot:插槽的名字="scoped" 插槽作用域变量  通过他去调用一些局部变量